package com.project.web.wechat.controller.app;

import com.project.common.core.utils.HttpUtil;
import com.project.common.core.utils.exception.Result;
import com.project.common.core.utils.id.IDUtil;
import com.project.common.core.utils.redis.RedisClient;
import com.project.web.util.exception.WeChatCustomException;
import com.project.web.util.exception.WECHAT_RESP_CODE_ENUM;
import com.project.web.wechat.controller.common.BaseController;
import com.project.web.wechat.model.app.TencentAdVo.Action;
import com.project.web.wechat.model.app.TencentAdVo.Trace;
import com.project.web.wechat.model.app.TencentAdVo.UserAction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * 腾讯开发者
 *
 * @Author: wyy
 * @Date: 12/17/20 3:58 PM
 */
@Api(tags = "腾讯开发者API")
@RestController("tencentAdDevController")
@RequestMapping("/weChat/tencentAdDev")
public class TencentAdDevController extends BaseController {
    // 日志工具类
    public static final Logger log = LoggerFactory.getLogger(TencentAdDevController.class);

    /**
     * 注入redis工具类
     */
    @Resource(name = "redisClient")
    private RedisClient redisClient;

    /**
     * 通过Redis获取AccessToken
     *
     * @return
     */
    @ApiOperation(value = "通过Redis获取AccessToken")
    @GetMapping(value = "/getAccessTokenOfRedis")
    public Result<Map<String, Object>> getAccessTokenOfRedis() {
        // 获取redis对应 TX_AD_ACCESS_TOKEN值
        Object txAdAccessToken = redisClient.get("TX_AD_ACCESS_TOKEN");
        Map<String, Object> resultMap = new HashMap<>();
        if (null == txAdAccessToken) {
            resultMap.put("flag", false);
        } else {
            resultMap.put("flag", true);
            resultMap.put("accessToken", txAdAccessToken);
        }
        return getResult(resultMap);
    }

    /**
     * 通过AuthorizationCode获取AccessToken
     *
     * @param clientId          应用id
     * @param clientSecret      应用secret
     * @param grantType         请求的类型
     * @param authorizationCode OAuth 认证 code
     * @param refreshToken
     * @param redirectUri
     * @return
     */
    @ApiOperation(value = "通过AuthorizationCode获取AccessToken")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "clientId", value = "应用id", dataType = "Integer", required = true),
            @ApiImplicitParam(paramType = "query", name = "clientSecret", value = "应用secret", dataType = "String", required = true),
            @ApiImplicitParam(paramType = "query", name = "grantType", value = "请求的类型【authorization_code,refresh_token】", dataType = "String", required = true),
            @ApiImplicitParam(paramType = "query", name = "authorizationCode", value = "OAuth 认证 code", dataType = "String", required = true),
            @ApiImplicitParam(paramType = "query", name = "refreshToken", value = "应用 refresh token", dataType = "String", required = true),
            @ApiImplicitParam(paramType = "query", name = "redirectUri", value = "应用回调地址", dataType = "String", required = true)
    })
    @GetMapping(value = "/getAccessToken")
    public Result<String> getAccessToken(Integer clientId, String clientSecret, String grantType, String authorizationCode,
                                         String refreshToken, String redirectUri) {
        // 参数校验
        Map<String, Object> parameterMap = new HashMap<>();
        if (clientId == null || StringUtils.isBlank("clientSecret")) {
            throw new WeChatCustomException(WECHAT_RESP_CODE_ENUM.MISS_PARAMETER);
        }
        parameterMap.put("client_id", clientId);
        parameterMap.put("client_secret", clientSecret);
        parameterMap.put("grant_type", grantType);
        parameterMap.put("redirect_uri", redirectUri);
        if (StringUtils.isNotBlank(authorizationCode)) {
            parameterMap.put("authorization_code", authorizationCode);
        }
        if (StringUtils.isNotBlank(refreshToken)) {
            parameterMap.put("refresh_token", refreshToken);
        }

        // 请求腾讯接口
        JSONObject resultJsonObject = HttpUtil.getJSONObjectFromHttpsGet("https://api.e.qq.com/oauth/token", parameterMap);
        log.info("\r\n *************腾讯开发者getAccessToken返回数据:{}", resultJsonObject.toString());
        JSONObject dataJsonObject = (JSONObject) resultJsonObject.get("data");
        String accessToken = dataJsonObject.get("access_token").toString();

        // 存入redis
        if (StringUtils.isNotBlank(accessToken)) {
            redisClient.set("TX_AD_ACCESS_TOKEN", accessToken);
        }
        return getResult(accessToken);
    }

    /**
     * 腾讯AD信息流用户行为上报
     * RESERVATION
     *
     * @return
     */
    @ApiOperation(value = "腾讯AD信息流用户行为上报")
    @PostMapping(value = "/user_actions/add")
    public Result<Map<String, Object>> addUserActions(@RequestBody String clickId) {
        // 初始化用户行为请求参数
        UserAction userAction = new UserAction();
        String txAdAccessToken = redisClient.get("TX_AD_ACCESS_TOKEN").toString();
        userAction.setAccess_token(txAdAccessToken);
        userAction.setTimestamp(new Date().getTime());
        userAction.setNonce(String.valueOf(IDUtil.getId()));
        userAction.setAccount_id(18745926);
        userAction.setUser_action_set_id(1111324026);

        // 初始化行为参数
        Action action = new Action();
        action.setAction_time(new Date().getTime());
        action.setAction_type("RESERVATION");

        // 初始化跟踪参数
        Trace trace = new Trace();
        trace.setClick_id(clickId);
        action.setTrace(trace);

        // 初始化请求参数
        List<Action> actions = new ArrayList<>();
        actions.add(action);
        userAction.setActions(actions);

        // 上报接口
        HttpUtil.getJSONObjectFromHttpsPost("https://api.e.qq.com/v1.1/user_actions/add", JSONObject.fromObject(userAction));

        return getResult(null);
    }

}
